package com.test.service.impl;

import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.test.dao.UserMapper;
import com.test.entity.*;
import com.test.entity.config.UserDetail;
import com.test.entity.pojo.UserEntity;
import com.test.service.IResourceService;
import com.test.service.IUserService;
import com.test.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Author: admin
 * Date: 2022/11/17 9:43
 * Describe: TODO
 */
@Service
public class UserService extends ServiceImpl<UserMapper, UserEntity> implements IUserService, UserDetailsService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    IResourceService resourceService;

    @Autowired
    PasswordEncoder passwordEncoder;
    @Override
    public ResultEntity login(LoginParam param) {
        UserEntity user = userMapper.selectByUsername(param.getUsername());
        // 若没有查到用户 或者 密码校验失败则抛出自定义异常
        if (user == null || !passwordEncoder.matches(param.getPassword(), user.getPassword())) {
            throw new ApiException("账号密码错误");
        }

        // 需要返回给前端的VO对象
        UserVO userVO = new UserVO();
        userVO.setId(user.getId());
        userVO.setUsername(user.getUsername());
                // 生成JWT，将用户名数据存入其中
        userVO.setToken(JwtUtil.generate(user.getUsername()));
        return new ResultEntity(1,"操作成功", userVO);
    }

    @Override
    public ResultEntity deleteByUserName(@RequestBody String userName) {
        userMapper.deleteByUserName(userName);
        return new ResultEntity(1, "操作成功", "删除成功");
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 从数据库中查询出用户实体对象, 这里根据用户名查询，没有对密码进行判断,密码匹配是在authenticate方法进行的
        UserEntity user = userMapper.selectByUsername(username);
        // 若没查询到一定要抛出该异常，这样才能被Spring Security的错误处理器处理
        if (user == null) {
            throw new UsernameNotFoundException("没有找到该用户");
        }

        // 先将该用户所拥有的资源id全部查询出来，再转换成`SimpleGrantedAuthority`权限对象
        Set<SimpleGrantedAuthority> authorities = resourceService.getIdsByUserId(user.getId())
                .stream()
                .map(String::valueOf)
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toSet());
        // 走到这代表查询到了实体对象，那就返回我们自定义的UserDetail对象（这里权限暂时放个空集合，后面我会讲解）
        return new UserDetail(user, authorities);
    }
}
